
#include "templates.h"
#include <vector>
#include <string>
#include "Utils.h"
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
#include "SimpleBlobsLib.h"
#include "TrabalhoFinal.h"


void remove_blobs_invalidos(cv::Mat img, const cv::Rect &roi,std::vector<cv::Rect>&rects)
{

	if(rects.size()<=4)
		return;
	//for(int i = 0 ; i < rects.size();i++)
	for(auto it = rects.begin();it != rects.end();it++)
	{
		auto & rect = *it;
		const int centerX = rect.x+ rect.width/2;
		const int centerY = rect.y+ rect.height/2;
		const cv::Point pt(centerX,centerY);
		if(!pt.inside(roi))
		{
			img(rect) = 0;
			rects.erase(it);
			it = rects.begin();
		}
	}



	
	int rectsAntes = rects.size();
	std::sort(rects.begin(),rects.end(),[](const cv::Rect& r0,const cv::Rect& r1){return r0.area() < r1.area();});
	while(rects.size()> 4)
	{
		rects.erase(rects.begin());

	}
	
	static int cont = 0;
	//if(rectsAntes!=4)
	{
		cv::Mat tmpimg = img.clone();
		Utils::DrawObjectRects(rects,tmpimg,127);
		cv::imwrite("d:\\"+Utils::to_string(cont)+".bmp",tmpimg);

		cv::Mat tmpimg2 = img.clone();
		Utils::DrawObjectRects(rects,tmpimg2,127);
		cv::imwrite("d:\\"+Utils::to_string(cont)+"-.bmp",tmpimg2);


		//cv::waitKey();
	}
	cont++;
	
	

	std::sort(rects.begin(),rects.end(),[](const cv::Rect& r0,const cv::Rect& r1){return r0.x < r1.x;});


	return ;
}


std::vector<cv::Rect> DetectaCaracteres(const cv::Mat &im,const cv::Rect roi )
{
	auto rects  = Utils::DetectBlobAgglomeration(im,3,35,32,35);
	cv::Rect charRoiExtra = cv::Rect(roi.x-15,roi.y-10,roi.width+25,roi.height+20);
	remove_blobs_invalidos(im,charRoiExtra,rects);

	return rects;
}
	


cv::Rect DetectaRoi(const cv::Mat &im)
{
	const int threshold = 10;
	cv::Mat imThr;

	cv::threshold(im,imThr,threshold,255,cv::THRESH_BINARY_INV);

		
	int minX = INT_MAX,maxX=0,minY=INT_MAX,maxY=0;
	
	for(int x=4; x<im.cols-4; x++)
	{
		for(int y=4; y<im.rows-4; y++)
		{			
			if( imThr.at<uchar>(cv::Point(x,y))==255)
			{						
				int pixelCount = cv::countNonZero(imThr(cv::Rect(x-3,y-3,7,7))) ;
				if(pixelCount >= 3)
				{
					if( x < minX )minX = x;
					if( y < minY )minY = y;
					if( x > maxX )maxX = x;
					if( y > maxY )maxY = y;

				}
			}			
		}
	}
	

	cv::Rect rect(minX,minY,maxX-minX,maxY-minY);

	static int cont = 0 ;
	cv::rectangle(imThr,rect,127);
	//cv::imwrite("d:\\"+Utils::to_string(cont)+".bmp",imThr);

	cont ++;
	return rect;

}



int main(int argc, char**argv )
{
	
	if(argc < 2)
	{
		return -1;
	}


	std::vector<std::string> args(argv, argv + argc);

	std::vector<std::string>files;
	Utils::GetFilesInDirectory(args[1],"*.BMP",files);

	if(files.size()==0)
		files.push_back(args[1]);

	std::vector<std::string>acertos,erros,excecoes,separacaoErrada;
	TemplateMatching::Templates templates("C:\\Users\\William\\Dropbox\\trabalho\\CARACTERES\\separados\\");//selecionados\\");	


	size_t i;
	for( i = 0 ; i < files.size();i++)
	{
		try
		{
			auto &file = files[i];
			cv::Mat im = cv::imread(file),imProc = cv::imread(file,0);

			
			cv::Rect roi = ::DetectaRoi(imProc);
			imProc = ::Segmentacao(im,roi);

			 imProc = ::RemoveLinhas(imProc,roi);
			 auto chars = ::DetectaCaracteres(imProc,roi);
			//cv::imwrite("teste",imgProc);
			std::string resposta =  ::ReconheceCaracteres(imProc,chars,templates);
			std::string resCorreta = Utils::GetFileNameWithoutExtension(file);
			

			std::cout << "Verificando resposta(" + resposta + ")..."  ;
			if(Utils::ToLowerCase(resposta) == Utils::ToLowerCase(resCorreta))
			{
				acertos.push_back(resCorreta);
				std::cout << "ok"<< std::endl;
			}
			else
			{
				erros.push_back(resCorreta);
				std::cout << "erro" << std::endl;
			}
			

		}
		catch(std::exception & ex)
		{
			std::cout << ex.what();
			excecoes.push_back(files[i]);
		}
		catch(...)
		{
			std::cout << "erro desconhecido";
			excecoes.push_back(files[i]);
		}
	}



	return 0;
}

